
/**   
 * @Title: ImageUtil.java 
 * @Package: com.rename.icode.utils 
 * @Description: Administrator版权所有
 * @author Administrator  
 * @date 2015-2-12 下午4:22:45 
 * @version  
 */


package com.rename.icode.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/** 
 * @Description 实现了...功能
 * @author Administrator
 * @date 2015-2-12 下午4:22:45 
 * @version V1.0
 */

public class ImageUtil {
	/**
	 * 锟斤拷bitmap转锟斤拷锟斤拷锟街斤拷锟斤拷锟斤拷
	 * 
	 * @param bitmap锟斤拷锟斤拷
	 * @return 锟街斤拷锟斤拷锟斤拷锟斤拷锟斤拷
	 */
	public static byte[] bitmapToByte(Bitmap b) {
	    if (b == null) {
	        return null;
	    }

	    ByteArrayOutputStream o = new ByteArrayOutputStream();
	    // 压锟斤拷锟斤拷锟狡讹拷锟斤拷.PNG锟斤拷式
	    b.compress(Bitmap.CompressFormat.PNG, 100, o);
	    return o.toByteArray();
	}

	/**
	 * 锟斤拷锟皆硷拷锟斤拷锟斤拷转锟斤拷锟斤拷Bitmap
	 * 
	 * @param 锟街斤拷锟斤拷锟斤拷锟斤拷锟斤拷
	 * @return bitmap锟斤拷锟斤拷
	 */
	public static Bitmap byteToBitmap(byte[] b) {
	    return (b == null || b.length == 0) ? null : BitmapFactory
	            .decodeByteArray(b, 0, b.length);
	}

	/**
	 * 锟斤拷Drawable锟斤拷锟斤拷转锟斤拷锟斤拷Bitmap
	 * 
	 * @param Drawable锟斤拷锟斤拷
	 * @return bitmap锟斤拷锟斤拷
	 */
	public static Bitmap drawableToBitmap(Drawable d) {
	    return d == null ? null : ((BitmapDrawable) d).getBitmap();
	}

	/**
	 * 锟斤拷 Bitmap 锟斤拷锟斤拷转锟斤拷锟斤拷 Drawable
	 * 
	 * @param bitmap锟斤拷锟斤拷
	 * @return Drawable锟斤拷锟斤拷
	 */
	public static Drawable bitmapToDrawable(Bitmap b) {
	    return b == null ? null : new BitmapDrawable(b);
	}

	/**
	 * 锟斤拷 Drawable锟斤拷锟斤拷转锟斤拷锟斤拷 锟街斤拷锟斤拷锟斤拷
	 * 
	 * @param Drawable锟斤拷锟斤拷
	 * @return 锟街斤拷锟斤拷锟斤拷
	 */
	public static byte[] drawableToByte(Drawable d) {
	    return bitmapToByte(drawableToBitmap(d));
	}

	/**
	 * 锟斤拷锟街斤拷锟斤拷锟斤拷转锟斤拷锟斤拷 Drawable
	 * 
	 * @param 锟街斤拷锟斤拷锟斤拷
	 * @return Drawable
	 */
	public static Drawable byteToDrawable(byte[] b) {
	    return bitmapToDrawable(byteToBitmap(b));
	}

	/**
	 * 锟斤拷锟斤拷url锟斤拷取锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟截诧拷锟截憋拷锟斤拷锟斤拷锟斤拷
	 * 
	 * @param 锟斤拷锟斤拷url
	 * @param 锟斤拷取锟斤拷时
	 * @return 锟斤拷锟斤拷锟斤拷
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public static InputStream getInputStreamFromUrl(String imageUrl,
	        int readTimeOutMillis) {
//		//bug-fix:#1779
//		Log.i("ImageUtil", "getInputStreamFromUrl(...),before encode url:"+imageUrl);
	    InputStream stream = null;
//	    try {
//			imageUrl = URLEncoder.encode(imageUrl, "utf-8").replaceAll("%2F", "/").replace("%3A", ":").replace("%3F", "?");
//		} catch (UnsupportedEncodingException e1) {
//			e1.printStackTrace();
//		}
//	    
//	    Log.i("ImageUtil", "getInputStreamFromUrl(...),after encode url:"+imageUrl);
	    try {
	        URL url = new URL(imageUrl);
	        HttpURLConnection con = (HttpURLConnection) url.openConnection();
	        if (readTimeOutMillis > 0) {
	            con.setReadTimeout(readTimeOutMillis);
	        }
	        stream = con.getInputStream();
	    } catch (MalformedURLException e) {
	        closeInputStream(stream);
	        throw new RuntimeException("MalformedURLException occurred. ", e);
	    } catch (IOException e) {
	        closeInputStream(stream);
	        throw new RuntimeException("IOException occurred. ", e);
	    }
	    return stream;
	}

	/**
	 * 锟斤拷去url锟斤拷锟斤拷锟捷诧拷转锟斤拷锟斤拷drawable
	 * 
	 * @param 锟斤拷锟捷碉拷url
	 * @param 锟斤拷取锟斤拷时时锟斤拷
	 * @return
	 */
	public static Drawable getDrawableFromUrl(String imageUrl,
	        int readTimeOutMillis) {
	    InputStream stream = getInputStreamFromUrl(imageUrl, readTimeOutMillis);
	    Drawable d = Drawable.createFromStream(stream, "src");
	    closeInputStream(stream);
	    return d;
	}

	/**
	 * 通锟斤拷锟斤拷锟斤拷url锟斤拷取bitmap锟斤拷锟斤拷
	 * 
	 * @param 图片url
	 * @return bitmap锟斤拷锟斤拷
	 */
	public static Bitmap getBitmapFromUrl(String imageUrl, int readTimeOut) {
	    InputStream stream = getInputStreamFromUrl(imageUrl, readTimeOut);
	    Bitmap b = BitmapFactory.decodeStream(stream);
	    closeInputStream(stream);
	    return b;
	}
	
	public static byte[] getBytesFromUrl(String fileUrl, int readTimeOut) {
		 ByteArrayOutputStream outStream;
		Log.i("ImageUtil","getBytesFromUrl" + fileUrl);
		try {
		    InputStream inputStream = getInputStreamFromUrl(fileUrl, readTimeOut);
		    
		    outStream = new ByteArrayOutputStream();  
	        byte[] buffer = new byte[1024];  
	        int len = 0;  
	        while((len = inputStream.read(buffer)) != -1){  
	            outStream.write(buffer, 0, len);  
	        }  
		    closeInputStream(inputStream);
		    outStream.close();
		}
		catch (Exception e) {
			Log.i("ImageUtil","Exception" + e.toString());
			return null;
		}
        return outStream.toByteArray();  
	}
	
//	public static byte[] getBytesFromUrl(String fileUrl, long totalLen, int readTimeOut, FileRecvResultListener callback) {
//		 ByteArrayOutputStream outStream;
//		 int recvLen = 0;
//		 
//		try {
//		    InputStream inputStream = getInputStreamFromUrl(fileUrl, readTimeOut);
//		    
//		    outStream = new ByteArrayOutputStream();  
//	        byte[] buffer = new byte[1024];  
//	        int len = 0;  
//	        while((len = inputStream.read(buffer)) != -1){  
//	            outStream.write(buffer, 0, len);
//	            recvLen += len;
//	            callback.onRecvProgress(recvLen, totalLen);
//	        }  
//		    closeInputStream(inputStream);
//		    outStream.close();
//		}
//		catch (Exception e) {
//			callback.onRecvResult(false);
//			return null;
//		}
//		
//		callback.onRecvResult(true);
//        return outStream.toByteArray();  
//	}
	
//	public static boolean getOtaSrcFromUrl(String fileUrl, long totalLen, int readTimeOut, FileRecvResultListener callback,String apkname) {
//		 ByteArrayOutputStream outStream;
//		 int recvLen = 0;
//		 
//		try {
//		    InputStream inputStream = getInputStreamFromUrl(fileUrl, readTimeOut);
//		    
//		    outStream = new ByteArrayOutputStream();  
//	        byte[] buffer = new byte[1024];  
//	        int len = 0;  
//	        while((len = inputStream.read(buffer)) != -1){  
//	            outStream.write(buffer, 0, len);
//	            recvLen += len;
//	            callback.onRecvProgress(recvLen, totalLen);
//	        }  
//		    closeInputStream(inputStream);
//		    outStream.close();
//		}
//		catch (Exception e) {
//			callback.onRecvResult(false);
//			return false;
//		}
//		
//		FileOutputStream fout = null;
//        
//    	try {
//	    	File file = new File(FileUtil.getGlobalCachePath()+apkname);
//	    	fout = new FileOutputStream(file);
//	    	fout.write(outStream.toByteArray());
//	    	fout.close(); 
//    	} catch (IOException e) {
//	        throw new RuntimeException("IOException occurred when saving file: " + apkname, e);
//    	}
//    	callback.onRecvResult(true);
//       return true;  
//	}

//	public static ImageSize getVideoDisplaySizeByAvInfo(String info) {
//		try {
//			JSONObject avinfo = new JSONObject(info);
//			JSONArray streams = avinfo.getJSONArray("streams");
//			for (int i = 0; i < streams.length(); i ++) {
//				JSONObject stream = streams.getJSONObject(i);
//				if (stream.has("width") && stream.has("height")) {
//					ImageSize is = new ImageSize(stream.getInt("width"), stream.getInt("height"));
//					return is;
//				}
//			}
//			
//		} catch (JSONException e) {
//			e.printStackTrace();
//			return null;
//		}
//		
//		return null;
//	}
	
	
	 /** 
     * 锟斤拷锟斤拷图片锟斤拷锟侥硷拷 
     * @param bm 
     * @param fileName 
     * @throws IOException 
     */  
    public static void saveImage(Bitmap bm, String fileName) {  
    	try {
	        File myCaptureFile = new File(fileName);  
	        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));  
	        bm.compress(Bitmap.CompressFormat.JPEG, 85, bos);  
	        bos.flush();  
	        bos.close();  
    	} catch (IOException e) {
	        throw new RuntimeException("IOException occurred when saving image: " + fileName, e);
    	}
    } 
    
	 /** 
     * 锟斤拷锟斤拷锟侥硷拷 (byte[])
     * @param bm 
     * @param fileName 
     * @throws IOException 
     */  
    public static void saveFile(Context cntx, byte[] bytes, String fileName) throws IOException { 
    	FileOutputStream fout = null;
        
    	try {
	    	File file = new File(fileName);
	    	fout = new FileOutputStream(file);
	    	fout.write(bytes);
	    	fout.close(); 
    	} catch (IOException e) {
	        throw new RuntimeException("IOException occurred when saving file: " + fileName, e);
    	}
    } 
    
	/**
	 * 通锟斤拷锟斤拷叱锟斤拷锟斤拷锟斤拷锟酵计�
	 * 
	 * @param bitmap锟斤拷锟斤拷
	 * @param 锟铰的匡拷锟�
	 * @param 锟铰的高讹拷
	 * @return 锟斤拷锟脚猴拷锟�bitmap
	 */
	public static Bitmap scaleImageTo(Bitmap org, int newWidth, int newHeight) {
	    return scaleImage(org, (float) newWidth / org.getWidth(),
	            (float) newHeight / org.getHeight());
	}

	/**
	 * 通锟斤拷锟斤拷叩谋锟斤拷锟斤拷锟斤拷锟酵计�
	 * 
	 * @param bitmap锟斤拷锟斤拷
	 * @param 锟斤拷鹊谋锟斤拷锟�
	 * @param 锟竭度的憋拷锟斤拷
	 * @return 锟斤拷锟脚猴拷锟�bitmap
	 */
	public static Bitmap scaleImage(Bitmap org, float scaleWidth,
	        float scaleHeight) {
	    if (org == null) {
	        return null;
	    }

	    Matrix matrix = new Matrix();
	    matrix.postScale(scaleWidth, scaleHeight);
	    return Bitmap.createBitmap(org, 0, 0, org.getWidth(), org.getHeight(),
	            matrix, true);
	}
	
	/**
	 * 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟酵计�实锟绞尺达拷锟斤拷锟斤拷锟绞撅拷某叽锟斤拷远锟斤拷锟斤拷锟斤拷锟叫★拷锟斤拷锟�
	 * 锟斤拷Google code锟斤拷
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
	    // Raw height and width of image
	    final int height = options.outHeight;
	    final int width = options.outWidth;
	    int inSampleSize = 1;
	
	    if (height > reqHeight || width > reqWidth) {
	
	        final int halfHeight = height / 2;
	        final int halfWidth = width / 2;
	
	        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
	        // height and width larger than the requested height and width.
	        while ((halfHeight / inSampleSize) > reqHeight
	                && (halfWidth / inSampleSize) > reqWidth) {
	            inSampleSize *= 2;
	        }
	    }
	
	    return inSampleSize;
	}
	
	/**
	 * 锟斤拷锟侥硷拷锟叫讹拷取图片锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷示锟侥尺达拷锟皆讹拷锟斤拷小锟斤拷
	 * 锟斤拷Google Code锟斤拷
	 * @param imgPath
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static Bitmap decodeSampledBitmapFromFile(String imgPath,
	        int reqWidth, int reqHeight) {

	    // First decode with inJustDecodeBounds=true to check dimensions
	    final BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inJustDecodeBounds = true;
	    BitmapFactory.decodeFile(imgPath, options);

	    // Calculate inSampleSize
	    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

	    // Decode bitmap with inSampleSize set
	    options.inJustDecodeBounds = false;
	    return BitmapFactory.decodeFile(imgPath, options);
	}
	
	/**
	* 锟斤拷锟斤拷指锟斤拷锟斤拷图锟斤拷路锟斤拷锟酵达拷小锟斤拷锟斤拷取锟斤拷锟斤拷图
	* 锟剿凤拷锟斤拷锟斤拷锟斤拷锟斤拷么锟斤拷锟�
	* 1. 使锟矫斤拷小锟斤拷锟节达拷占洌�锟斤拷一锟轿伙拷取锟斤拷bitmap实锟斤拷锟斤拷为null锟斤拷只锟斤拷为锟剿讹拷取锟斤拷群透叨龋锟�
	* 锟节讹拷锟轿讹拷取锟斤拷bitmap锟角革拷锟捷憋拷锟斤拷压锟斤拷锟斤拷锟斤拷图锟斤拷锟斤拷锟斤拷味锟饺★拷锟�bitmap锟斤拷锟斤拷要锟斤拷锟斤拷锟斤拷图锟斤拷
	* 2. 锟斤拷锟斤拷图锟斤拷锟斤拷原图锟斤拷锟斤拷锟斤拷没锟斤拷锟斤拷锟届，锟斤拷锟斤拷使锟斤拷锟斤拷2.2锟芥本锟斤拷锟铰癸拷锟斤拷ThumbnailUtils锟斤拷使
	* 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷傻锟酵硷拷锟结被锟斤拷锟届。
	* @param imagePath 图锟斤拷锟铰凤拷锟�
	* @param width 指锟斤拷锟斤拷锟酵硷拷锟侥匡拷锟�
	* @param height 指锟斤拷锟斤拷锟酵硷拷锟侥高讹拷
	* @return 锟斤拷锟缴碉拷锟斤拷锟斤拷图
	*/
	public static Bitmap getImageThumbnail(String imagePath, int width, int height) {
		Bitmap bitmap = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		// 锟斤拷取锟斤拷锟酵计�锟侥匡拷透撸锟阶�锟斤拷舜锟斤拷锟�bitmap为null
		bitmap = BitmapFactory.decodeFile(imagePath, options);
		options.inJustDecodeBounds = false; // 锟斤拷为 false
		// 锟斤拷锟斤拷锟斤拷锟脚憋拷
		int h = options.outHeight;
		int w = options.outWidth;
		int beWidth = w / width;
		int beHeight = h / height;
		int be = 1;
		if (beWidth < beHeight) {
			be = beWidth;
		} else {
			be = beHeight;
		}
		if (be <= 0) {
			be = 1;
		}
		options.inSampleSize = be;
		// 锟斤拷锟铰讹拷锟斤拷图片锟斤拷锟斤拷取锟斤拷锟脚猴拷锟�bitmap锟斤拷注锟斤拷锟斤拷锟揭�锟斤拷options.inJustDecodeBounds 锟斤拷为 false
		bitmap = BitmapFactory.decodeFile(imagePath, options);
		// 锟斤拷锟斤拷ThumbnailUtils锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷图锟斤拷锟斤拷锟斤拷要指锟斤拷要锟斤拷锟斤拷锟侥革拷Bitmap锟斤拷锟斤拷
		bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
		ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
		return bitmap;
	}

	/**
	* 锟斤拷取锟斤拷频锟斤拷锟斤拷锟斤拷图
	* 锟斤拷通锟斤拷ThumbnailUtils锟斤拷锟斤拷锟斤拷一锟斤拷锟斤拷频锟斤拷锟斤拷锟斤拷图锟斤拷然锟斤拷锟斤拷锟斤拷锟斤拷ThumbnailUtils锟斤拷锟斤拷锟斤拷指锟斤拷锟斤拷小锟斤拷锟斤拷锟斤拷图锟斤拷
	* 锟斤拷锟斤拷锟揭�锟斤拷锟斤拷锟斤拷图锟侥匡拷透叨锟叫★拷锟�MICRO_KIND锟斤拷锟斤拷锟斤拷锟斤拷要使锟斤拷MICRO_KIND锟斤拷为kind锟斤拷值锟斤拷锟斤拷锟斤拷锟斤拷锟绞★拷诖妗�
	* @param videoPath 锟斤拷频锟斤拷路锟斤拷
	* @param width 指锟斤拷锟斤拷锟斤拷锟狡碉拷锟斤拷锟酵硷拷目锟斤拷
	* @param height 指锟斤拷锟斤拷锟斤拷锟狡碉拷锟斤拷锟酵硷拷母叨榷锟�
	* @param kind 锟斤拷锟斤拷MediaStore.Images.Thumbnails锟斤拷锟叫的筹拷锟斤拷MINI_KIND锟斤拷MICRO_KIND锟斤拷
	* 锟斤拷锟叫ｏ拷MINI_KIND: 512 x 384锟斤拷MICRO_KIND: 96 x 96
	* @return 指锟斤拷锟斤拷小锟斤拷锟斤拷频锟斤拷锟斤拷图
	*/
	public static Bitmap getVideoThumbnail(String videoPath, int width, int height, int kind) {
		Bitmap bitmap = null;
		// 锟斤拷取锟斤拷频锟斤拷锟斤拷锟斤拷图
		bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
		bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
		ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
		return bitmap;
	}
	
	public static Bitmap getVideoThumbnail(String videoPath, int kind) {
		Bitmap bitmap = null;
		// 锟斤拷取锟斤拷频锟斤拷锟斤拷锟斤拷图
		bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
		return bitmap;
	}
	
	/**
	 * 锟截憋拷锟斤拷锟斤拷锟斤拷
	 * 
	 * @param 锟斤拷锟斤拷锟斤拷
	 */
	private static void closeInputStream(InputStream s) {
	    if (s == null) {
	        return;
	    }

	    try {
	        s.close();
	    } catch (IOException e) {
	        throw new RuntimeException("IOException occurred. ", e);
	    }
	}
	/**
	 * bug fix 1864
	 * @param bitmap
	 * @return
	 */
	public static Bitmap checkBitmapSize(Bitmap bitmap){
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		if(w<=4096&&h<=4096){
			return bitmap;
		}else{
			if(h>4096){
				float scale = (float)fix((double)4000/h, 100000000);
				matrix.setScale(scale,scale);
				return Bitmap.createBitmap(bitmap, 0, 0, w, h,matrix , true);
			}else if(w>4096){
				float scale = (float)fix((double)4000/w, 100000000);
				matrix.setScale(scale,scale);
				return Bitmap.createBitmap(bitmap, 0, 0, w, h,matrix , true);
			}
		}
		return bitmap;
	}
	private static  double fix(double val, int fix) {
		if (val == 0)
			return (double)val;
		int p = (int) Math.pow(10, fix);
		return (double) ((int) (val * p)) / p;
	}
}
